/*
 * Copyright (c) 2020 hebeiyiliuba.com
 * All rights reserved.
 *
 */
package org.jeecg.modules.third.getui.push;

import com.getui.push.v2.sdk.ApiHelper;
import com.getui.push.v2.sdk.GtApiConfiguration;
import com.getui.push.v2.sdk.api.PushApi;
import com.getui.push.v2.sdk.api.StatisticApi;
import com.getui.push.v2.sdk.api.UserApi;
import com.getui.push.v2.sdk.common.ApiResult;
import com.getui.push.v2.sdk.dto.req.Audience;
import com.getui.push.v2.sdk.dto.req.AudienceDTO;
import com.getui.push.v2.sdk.dto.req.Settings;
import com.getui.push.v2.sdk.dto.req.Strategy;
import com.getui.push.v2.sdk.dto.req.message.PushDTO;
import com.getui.push.v2.sdk.dto.req.message.PushMessage;
import com.getui.push.v2.sdk.dto.req.message.android.GTNotification;
import com.getui.push.v2.sdk.dto.res.CidStatusDTO;
import com.getui.push.v2.sdk.dto.res.ScheduleTaskDTO;
import com.getui.push.v2.sdk.dto.res.TaskIdDTO;
import com.getui.push.v2.sdk.dto.res.statistic.StatisticDTO;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.third.getui.push.constant.GetuiConstant;
import org.jeecg.modules.wlhy.utils.HyConfigUtils;
import org.jeecg.modules.wlhy.hyconfig.entity.HyConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 个推消息推送
 *
 * @author duanlikao
 * @created 2021/6/1
 */
@Service
public class GetuiPushService {

    private static final Logger LOGGER = LoggerFactory.getLogger(GetuiPushService.class);


    public PushApi pushApi;

    public StatisticApi statisticApi;

    public UserApi userApi;

    public void buildApi(String pushTpye){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getTsIzUse()){
            throw new JeecgBootException("个推消息推送服务暂未开启,请联系管理员。");
        }

        GtApiConfiguration apiConfiguration = new GtApiConfiguration();

        //设置代理对象，参数依次为host、端口、鉴权账户、鉴权密码。其中鉴权账户密码可选
//        GtHttpProxyConfig proxyConfig = new GtHttpProxyConfig("xxx",xxx,"xxx","xxx");
//        apiConfiguration.setProxyConfig(proxyConfig);

        //填写应用配置
        apiConfiguration.setAppId(
                "driver".equals(pushTpye) ?  systemConfig.getTsDriverAppid() : systemConfig.getTsCustomerAppid()
        );
        apiConfiguration.setAppKey(
                "driver".equals(pushTpye) ?  systemConfig.getTsDriverAppkey() : systemConfig.getTsCustomerAppkey()
        );
        apiConfiguration.setMasterSecret(
                "driver".equals(pushTpye) ?  systemConfig.getTsDriverMastersecret() : systemConfig.getTsCustomerMastersecret()
        );
        // 接口调用前缀，请查看文档: 接口调用规范 -> 接口前缀, 可不填写appId
        apiConfiguration.setDomain(GetuiConstant.BASEURL);
        // 实例化ApiHelper对象，用于创建接口对象
        ApiHelper apiHelper = ApiHelper.build(apiConfiguration);
        // 创建对象，建议复用。目前有PushApi、StatisticApi、UserApi
        pushApi         = apiHelper.creatApi(PushApi.class);
        statisticApi    = apiHelper.creatApi(StatisticApi.class);
        userApi         = apiHelper.creatApi(UserApi.class);
    }

    /**
     * 根据cid进行单推
     * @param notification
     * @param cid
     * @return
     */
    public boolean  pushToSingleByCid(GTNotification notification ,String cid){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getTsIzUse()){
            throw new JeecgBootException("个推消息推送服务暂未开启,请联系管理员。");
        }
        PushDTO pushDTO = new PushDTO<>();
        // 设置推送参数
        pushDTO.setRequestId(System.currentTimeMillis() + "");

        //配置推送条件
        // 1: 表示该消息在用户在线时推送个推通道，用户离线时推送厂商通道;
        // 2: 表示该消息只通过厂商通道策略下发，不考虑用户是否在线;
        // 3: 表示该消息只通过个推通道下发，不考虑用户是否在线；
        // 4: 表示该消息优先从厂商通道下发，若消息内容在厂商通道代发失败后会从个推通道下发。
        Strategy strategy = new Strategy();
        strategy.setDef(1);
        Settings settings = new Settings();
        settings.setStrategy(strategy);
        pushDTO.setSettings(settings);
        //消息离线时间设置，单位毫秒，-1表示不设离线，-1 ～ 3 * 24 * 3600 * 1000(3天)之间
        settings.setTtl(3 * 24 * 3600 * 1000);//消息有效期，走厂商消息需要设置该值

        //安卓离线厂商通道推送消息体
//        PushChannel pushChannel = new PushChannel();
//        AndroidDTO androidDTO = new AndroidDTO();
//        Ups ups = new Ups();
//        ThirdNotification notification1 = new ThirdNotification();;
//        ups.setNotification(notification1);
//        notification1.setTitle("安卓离线展示的标题");
//        notification1.setBody("安卓离线展示的内容");
//        notification1.setClickType("intent");
//        notification1.setIntent("intent:#Intent;launchFlags=0x04000000;action=android.intent.action.oppopush;component=io.dcloud.HBuilder/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=测试标题;S.content=测试内容;S.payload=test;end");
//        //各厂商自有功能单项设置
//        ups.addOption("HW", "/message/android/notification/badge/class", "io.dcloud.PandoraEntry ");
//        //ups.addOption("HW", "/message/android/notification/badge/add_num", 1);
//        //ups.addOption("HW", "/message/android/notification/importance", "HIGH");
//        //ups.addOption("VV","classification",1);
//        androidDTO.setUps(ups);
//        pushChannel.setAndroid(androidDTO);
//        pushDTO.setPushChannel(pushChannel);

        PushMessage pushMessage = new PushMessage();
        //通知消息
        pushMessage.setNotification(notification);
        //透传
//        pushMessage.setTransmission("{title:\"标题\",content:\"内容\",payload:\"自定义数据\"}");
        pushDTO.setPushMessage(pushMessage);
        // 设置接收人信息
        Audience audience = new Audience();
        audience.addCid(cid);
        pushDTO.setAudience(audience);
        ApiResult <Map<String, Map <String, String>>> apiResult = pushApi.pushToSingleByCid(pushDTO);
        return apiResult.isSuccess() ? true : false;
    }

    /**
     * 执行cid批量推 前置任务
     * @param notification
     * @return
     */
    public ApiResult <TaskIdDTO> createMsg(GTNotification notification){

        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getTsIzUse()){
            throw new JeecgBootException("个推消息推送服务暂未开启,请联系管理员。");
        }
        PushDTO pushDTO = new PushDTO<>();
        // 设置推送参数
        pushDTO.setRequestId(System.currentTimeMillis() + "");
        Strategy strategy = new Strategy();
        strategy.setDef(1);
        Settings settings=new Settings();
        settings.setStrategy(strategy);
        pushDTO.setSettings(settings);
        settings.setTtl(3 * 24 * 3600 * 1000);//消息有效期，走厂商消息需要设置该值

        PushMessage pushMessage = new PushMessage();
        pushMessage.setNotification(notification);
        pushDTO.setPushMessage(pushMessage);

        ApiResult <TaskIdDTO> apiResult  =  pushApi.createMsg(pushDTO);
        return apiResult;
    }

    /**
     * 执行cid批量推 先创建消息任务
     * @param cids  cid数组，数组长度不大于200
     * @param taskId
     * @return
     */
    public ApiResult <Map<String, Map <String, String>>>  pushListByCid(List<String> cids ,String taskId ){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getTsIzUse()){
            throw new JeecgBootException("个推消息推送服务暂未开启,请联系管理员。");
        }
        // 设置接收人信息
        Audience audience = new Audience();
        audience.setCid(cids);
        AudienceDTO audienceDTO= new AudienceDTO();
        audienceDTO.setAudience(audience);
        audienceDTO.setTaskid(taskId);
        ApiResult <Map<String, Map <String, String>>> apiResults  =  pushApi.pushListByCid(audienceDTO);
        return apiResults;
    }



    /**
     * 执行群推
     * @param notification
     * @return
     */
    public ApiResult <TaskIdDTO>  pushAll(GTNotification notification){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getTsIzUse()){
            throw new JeecgBootException("个推消息推送服务暂未开启,请联系管理员。");
        }
        PushDTO pushDTO = new PushDTO<>();
        pushDTO.setRequestId(System.currentTimeMillis() + "");
        Strategy strategy = new Strategy();
        strategy.setDef(1);
        Settings settings=new Settings();
        settings.setStrategy(strategy);
        pushDTO.setSettings(settings);
        settings.setTtl(3 * 24 * 3600 * 1000);//消息有效期，走厂商消息需要设置该值
        PushMessage pushMessage = new PushMessage();
        pushMessage.setNotification(notification);
        pushDTO.setPushMessage(pushMessage);
        // 设置接收人信息
        Audience audience = new Audience();
        audience.setAll("all");
        pushDTO.setAudience(audience);
        ApiResult <TaskIdDTO> apiResult = pushApi.pushAll(pushDTO);
        return apiResult;
    }

    /**
     * 停止任务 对正处于推送状态，或者未接收的消息停止下发（只支持批量推和群推任务）
     * @param taskId
     * @return
     */
    public boolean stopPush(String taskId){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getTsIzUse()){
            throw new JeecgBootException("个推消息推送服务暂未开启,请联系管理员。");
        }
        ApiResult <Void> apiResult = pushApi.stopPush(taskId);
        return apiResult.isSuccess() ? true: false;
    }

    /**
     * 查询定时任务 该接口支持在推送完定时任务之后，查看定时任务状态，定时任务是否发送成功。
     * @param taskId
     * @return
     */
    public boolean  queryScheduleTask(String taskId){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getTsIzUse()){
            throw new JeecgBootException("个推消息推送服务暂未开启,请联系管理员。");
        }
        ApiResult <Map<String, ScheduleTaskDTO>>  apiResult = pushApi.queryScheduleTask(taskId);
        return apiResult.isSuccess() ? true : false;
    }

    /**
     * 删除定时任务 用来删除还未下发的任务，
     * 删除后定时任务不再触发(距离下发还有一分钟的任务，将无法删除，后续可以调用停止任务接口。
     * @param taskId
     * @return
     */
    public boolean   deleteScheduleTask(String taskId){
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if(systemConfig == null || !systemConfig.getTsIzUse()){
            throw new JeecgBootException("个推消息推送服务暂未开启,请联系管理员。");
        }
        ApiResult <Void>  apiResult = pushApi.deleteScheduleTask(taskId);
        return apiResult.isSuccess() ? true: false;
    }

    public static void main(String[] args) {
        GetuiPushService getuiPushService = new GetuiPushService();
        getuiPushService.buildApi("driv23er");

        GTNotification notification = new GTNotification();
        notification.setTitle("测试推送0605" + new Date());
        notification.setBody("测试推送内容0605");
        notification.setClickType("payload");
        notification.setPayload("【河北一六八网络科技】");

        String cid = "ac49f5b825e53d17df9c6fc1b18ba4af";
        getuiPushService.pushToSingleByCid(notification,cid);

//        getuiPushService. pushAll(notification);

        List<String> cids = new ArrayList <>();
        cids.add("ac49f5b825e53d17df9c6fc1b18ba4af");
        ApiResult <TaskIdDTO>  ab = getuiPushService.createMsg(notification);
        TaskIdDTO a =  ab.getData();
        getuiPushService.pushListByCid(cids,a.getTaskId());

//        getuiPushService.queryPushResultByTaskIds();
//        getuiPushService.queryUserStatus();
    }

    public void  queryPushResultByTaskIds(){
        // 获取单日推送数据
        Set <String> taskIds = new HashSet <String>();
        taskIds.add("RASA_0601_c03a05fed3ecb86d2ac3748eb2dfec3d");
        ApiResult<Map<String, Map<String, StatisticDTO>>> apiResult = statisticApi.queryPushResultByTaskIds(taskIds);
        if (apiResult.isSuccess()) {
            // success
            System.out.println(apiResult.getData());
        } else {
            // failed
            System.out.println("code:" + apiResult.getCode() + ", msg: " + apiResult.getMsg());
        }
    }

    public void   queryUserStatus(){
        Set<String> cids = new HashSet<String>();
        cids.add("216f39876550b2ef6b5908cd727ed907");
        // 查询用户状态
        ApiResult<Map<String, CidStatusDTO>> apiResult = userApi.queryUserStatus(cids);
        if (apiResult.isSuccess()) {
            // success
            System.out.println(apiResult.getData());
        } else {
            // failed
            System.out.println("code:" + apiResult.getCode() + ", msg: " + apiResult.getMsg());
        }
    }
}
